﻿#region Using
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
#endregion Using

namespace LloydGame
{
    public class GameScreen
    {
        #region Fields
        protected String m_title;
        protected Game m_game;
        protected SpriteFont m_titlefont;
        protected SpriteFont m_normalfont;
        protected SpriteFont m_smallfont;
        protected SpriteFont m_tinyfont;
        protected SpriteBatch m_spriteBatch;
        
        // Keyboard (or gamepad in future?) control
        protected bool m_keyboard_control;
        protected int m_selected_component;
        protected List<GameScreenComponent> m_selectable_components;

        // Subscreens and owner
        public GameScreen m_ownerscreen;
        protected GameScreen m_subscreen;
        protected bool m_rendersubscreen;
        protected KeyboardState m_currentkeyboard;
        protected KeyboardState m_lastkeyboard;
        protected bool m_activatetrigger;

        // Mouse interaction
        protected MouseState m_currentmouse;
        protected MouseState m_lastmouse;

        // Transition vars
        protected float m_slide_x;
        protected bool m_ready;
        protected Matrix m_screenmatrix;
        #endregion Fields

        #region Constructor
        public GameScreen(Game p_game, String p_title)
        {
            m_title = p_title;
            m_game = p_game;

            m_titlefont = ((Game1)p_game).menuFontBig;
            m_normalfont = ((Game1)p_game).menuFontNormal;
            m_smallfont = ((Game1)p_game).menuFontSmall;
            m_tinyfont = ((Game1)p_game).menuFontTiny;
            m_spriteBatch = new SpriteBatch(p_game.GraphicsDevice);

            m_ownerscreen = null;
            m_rendersubscreen = false;
            m_slide_x = p_game.GraphicsDevice.Viewport.Width;

            m_selectable_components = new List<GameScreenComponent>();
            m_ready = false;
        }
        #endregion

        #region Update
        public virtual void Update(GameTime p_gametime)
        {
            // Transition
            if (m_slide_x > 0)
            {
                m_slide_x -= m_slide_x / 8.0f;
                if (m_slide_x < 200)
                    m_ready = true;
            }

            // Subscreens
            if (m_rendersubscreen)
            {
                m_subscreen.Update(p_gametime);
                m_activatetrigger = false;
            }
            else
            {
                // Check trigger
                m_activatetrigger = ActivateTrigger();
            }

            // If mouse have moved, clear active
            if (m_lastmouse.X != m_currentmouse.X || m_lastmouse.Y != m_currentmouse.Y)
            {
                // Deactivate all
                foreach (GameScreenComponent t_component in m_selectable_components)
                {
                    t_component.Active = false;
                }
            }

            // Keyboard control
            if (!m_rendersubscreen &&
                m_selectable_components != null &&
                m_selectable_components.Count > 0)
            {
                

                // Change selection?
                if (m_currentkeyboard.IsKeyDown(Keys.Down) && m_lastkeyboard.IsKeyUp(Keys.Down))
                {
                    // Deactivate all
                    foreach (GameScreenComponent t_component in m_selectable_components)
                    {
                        t_component.Active = false;
                    }

                    m_selected_component++;

                    // Out of bounds check
                    if (m_selected_component > m_selectable_components.Count - 1)
                        m_selected_component = 0;

                    // Activate current
                    m_selectable_components[m_selected_component].Active = true;

                }
                else if (m_currentkeyboard.IsKeyDown(Keys.Up) && m_lastkeyboard.IsKeyUp(Keys.Up))
                {
                    // Deactivate all
                    foreach (GameScreenComponent t_component in m_selectable_components)
                    {
                        t_component.Active = false;
                    }

                    m_selected_component--;

                    // Out of bounds check
                    if (m_selected_component < 0)
                        m_selected_component = m_selectable_components.Count - 1;

                    // Activate current
                    m_selectable_components[m_selected_component].Active = true;
                }

                
            }

            
        }
        #endregion

        #region StoreStates
        public void StoreStates()
        {
            // Store mouse and keyboard state
            m_lastmouse = Mouse.GetState();
            m_lastkeyboard = Keyboard.GetState();
        }
        #endregion StoreStates

        #region Draw
        public virtual void Draw()
        {
            m_screenmatrix = Matrix.CreateTranslation(m_slide_x, 0, 0);
            float t_alpha = (((Game1)m_game).GraphicsDevice.Viewport.Width - m_slide_x) / ((Game1)m_game).GraphicsDevice.Viewport.Width;

            // Only render our title if we are active
            if (!m_rendersubscreen)
            {
                m_spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.None, m_screenmatrix);
                m_spriteBatch.DrawString(m_titlefont, m_title, new Vector2(71, 41), new Color(Color.Black, t_alpha));
                m_spriteBatch.DrawString(m_titlefont, m_title, new Vector2(70, 40), new Color(Color.White, t_alpha));
                m_spriteBatch.End();
            }
        }
        #endregion Draw

        #region StartSubscreen
        public void StartSubscreen(GameScreen p_newscreen)
        {
            m_subscreen = p_newscreen;
            m_rendersubscreen = true;
        }
        #endregion

        #region ReEntry
        public virtual void ReEntry()
        {
            m_ready = false;
            m_slide_x = m_game.GraphicsDevice.Viewport.Width;
            m_screenmatrix = Matrix.CreateTranslation(m_slide_x, 0, 0);
        }
        #endregion ReEntry

        #region Close
        public void Close()
        {
            if (m_ownerscreen != null)
            {
                m_ownerscreen.ReEntry();
                m_ownerscreen.m_rendersubscreen = false;
                m_ownerscreen.m_subscreen = null;
            }
        }
        #endregion Close

        #region ActivateTrigger
        public bool ActivateTrigger()
        {
            m_currentkeyboard = Keyboard.GetState();
            m_currentmouse = Mouse.GetState();
            if ((m_currentmouse.LeftButton == ButtonState.Pressed &&
                m_lastmouse.LeftButton == ButtonState.Released) ||
                (m_currentkeyboard.IsKeyDown(Keys.Enter) &&
                m_lastkeyboard.IsKeyUp(Keys.Enter))
                )
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion ActivateTrigger

    }
}
